﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PessModel;
using System.Data;
using System.Web.Security;

namespace PessMvc.Controllers
{
    [Authorize]
    public class RuleController : Controller
    {
        //
        // GET: /Rule/
        PESSEntities db;
        public RuleController()
        {
            db = new PESSEntities();
        }

        public ActionResult Index(int activityID)
        {
            var subjects = db.Activities.Find(activityID).Subjects;
            string userName = Membership.GetUser().UserName;
            if (Roles.IsUserInRole(Membership.GetUser().UserName, "ExpertJudge"))
            {
                //throw new Exception("FK between Subject and ExpertGroup has been removed!");
                var expertJudge=db.ExpertJudges.Find(userName);

                var subjectIDs = (from eg in expertJudge.ExpertGroups
                                 join a in db.Archives on eg.ActivityID equals a.Subject.ActivityID
                                 where eg.ActivityID == activityID
                                 select a.SubjectID).Distinct();
                subjects = subjects.Where(s => subjectIDs.Contains(s.ID)).ToList();
            }
            return View(subjects);
        }

        public ActionResult Details(int subjectID)
        {
            var subject1=db.Subjects.Find(subjectID);
            var rules = subject1.Rules;
            ViewData["subjectID1"] = subjectID;
            int activityID = subject1.ActivityID;
            ViewBag.SubjectName = subject1.Name;
            ViewBag.ActivityID = activityID;
            ViewBag.SubjectID = new SelectList(db.Subjects.Where(s => s.ActivityID == activityID&&s.Name!=subject1.Name),"ID","Name");

            //Show or hide the create new rule button.
            MembershipUser user=Membership.GetUser();
            var expertJudge=db.ExpertJudges.Find(user.UserName);
            ViewBag.ShowCreateRuleButton=false;
            ViewBag.AllowExpertLeaderSetRules = false;
            if (Roles.IsUserInRole("Admin"))
            {
                ViewBag.ShowCreateRuleButton=true;
            }
            //This sectionn is commented out because now an ExpertJudge can join multiple Groups. Code here needs to be fixed later!!!
            //else if(expertJudge.ExpertGroup.LeaderID != null && expertJudge.ExpertGroup.LeaderID == user.UserName && expertJudge.ExpertGroup.SubjectID == subjectID)
            //{
            //    if (db.Subjects.Find(subjectID).AllowExpertLeaderSetRules != null)//see if AllowExpertLeaderSetRules is null.
            //    {
            //        var subject=db.Subjects.Find(subjectID);
            //        ViewBag.AllowExpertLeaderSetRules=subject.AllowExpertLeaderSetRules;
            //        ViewBag.ShowCreateRuleButton = subject.AllowExpertLeaderSetRules;
            //    }
            //    else
            //    {
            //        ViewBag.ShowCreateRuleButton = false;
            //    }
            //}
            
            return View(rules);
        }

        public ActionResult Create(int subjectID)
        {
            ViewBag.SubjectID = subjectID;
            return View();
        }

        [HttpPost]
        public ActionResult Create(PessModel.Rule rule)
        {
            ViewBag.SubjectID = rule.SubjectID;
            if (ModelState.IsValid)
            {
                db.Rules.Add(rule);
                db.SaveChanges();
                return RedirectToAction("Details", new { subjectID = rule.SubjectID });
            }
            else
            {
                return View(rule);
            }
        }

        public ActionResult Edit(int ruleID)
        {
            return View(db.Rules.Find(ruleID));
        }

        [HttpPost]
        public ActionResult Edit(PessModel.Rule rule)
        {
            if (ModelState.IsValid)
            {
                db.Entry(rule).State = EntityState.Modified;
                db.SaveChanges();

                return RedirectToAction("Details", new { subjectID = rule.SubjectID });
            }
            return View(rule);
        }

        public ActionResult Delete(int ruleID)
        {
            return View(db.Rules.Find(ruleID));
        }

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int ruleID)
        {
            var rule = db.Rules.Find(ruleID);
            int subjectID = rule.SubjectID;
            if (rule.Scores.Count == 0)
            {
                db.Rules.Remove(rule);
                db.SaveChanges();
                return RedirectToAction("Details", new { subjectID = subjectID });
            }
            else
            {
                return RedirectToAction("Delete", new { ruleID = ruleID });
            }            
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="targetSubjectID"></param>
        /// <param name="subjectID">Source</param>
        /// <returns></returns>
        [HttpPost]
        [Authorize(Roles="Admin")]
        public ActionResult CopyRulesFromSubject(int targetSubjectID, int subjectID)
        {
            var targetSubject = db.Subjects.Find(targetSubjectID);
            var sourceSubject = db.Subjects.Find(subjectID);
            if (targetSubject != null && sourceSubject != null //Target and source subject both exist.
                && targetSubject.ActivityID == sourceSubject.ActivityID //under the same activity.
                &&targetSubject.Rules.Count==0 //target has no rules.
                &&sourceSubject.Rules.Count>0) //source has rules.
            {
                var sourceRules = from s in sourceSubject.Rules
                                  select new PessModel.Rule() { Name = s.Name, Description = s.Description, SubjectID = targetSubjectID, Value = s.Value, InputControl=s.InputControl };
                foreach (var r in sourceRules)
                {
                    db.Rules.Add(r);
                }                
                db.SaveChanges();

                targetSubject.ScoringInstruction = sourceSubject.ScoringInstruction;
                db.Entry(targetSubject).State = EntityState.Modified;
                db.SaveChanges();
            }
            return RedirectToAction("Details", "Rule", new { subjectID = targetSubjectID });
        }
    }
}
